local path = {
  "script/",
  "script/module/",
}

adj = adj or {}
envs = envs or {}
file_last_modify_time = file_last_modify_time or {} 
loaded = loaded or {}    
str2filename = str2filename or {}
local sta = {}
tb_loadfile = tb_loadfile or {}
local require_cnt = 0
function require(str, not_need_exist)
  require_cnt = require_cnt + 1 
  adj[str] = adj[str] or {}
  if sta[#sta] then
    adj[str][sta[#sta]] = true 
  end
  sta[#sta + 1] = str
  if not loaded[str] then
    loaded[str] = true 
    envs[str] = envs[str] or {
      _G = _G,
      assert = assert,
      error = error,
      ipairs = ipairs,
      load = load,
      next = next,
      pairs = pairs,
      pcall = pcall,
      print = print,
      require = require,
      setmetatable = setmetatable,
      tonumber = tonumber,
      tostring = tostring, 
      type = type,
       
      debug = debug, 
      io = io,   
      math = math,  
      string = string,
      table = table, 
      os = os, 
    } 
    envs[str]._ENV = envs[str]
    if not str2filename[str] then 
      local filename = string.gsub(str, "%.", "/") .. ".lua"
      local ac 
      for _, v in ipairs(path) do
        local pre_filename = v .. filename
        local a = get_file_last_modify_time(pre_filename)
        if a ~= 0 then
          str2filename[str] = pre_filename
          file_last_modify_time[str] = a
          ac = true 
          break
        end
      end
      if not ac then
        if not_need_exist then
          return
        else
          assert(nil, str .. " not exist")
        end
      end
    end
    local fun = tb_loadfile[str]
    if not fun then 
      local err
      
      fun, err = loadfile(str2filename[str], nil, envs[str])
      
      if not fun then
        assert(nil, err)
      end
    end
    local require_cnt_old = require_cnt
    fun()
    if require_cnt_old < require_cnt then  
      tb_loadfile[str] = fun
    end 
  end  
  sta[#sta] = nil
  return envs[str]
end


local MapEx = require("core.MapEx")
local cg = {}
local function get_cg(name)
	local mm = cg[name]
	if mm then
		return mm
	end
	mm = {}
	mm[1] = msg_ex.get_proto_id(name)
	cg[name] = mm
	return mm
end

local gc = {}
local function get_gc(name)
	local mm = gc[name]
	if mm then
		return mm
	end
	mm = {}
	if name == "GC_ENTER_SCENE" then
		mm.loadList = {}
		for i = 1, 16 do
			mm.loadList[i] = {}
		end
  elseif name == "GC_HUMAN_DIE" then
    mm.revive_item = {}
    for i = 1, 4 do
        mm.revive_item[i] = {}
    end
	end
	gc[name] = mm
	return mm
end

local function send(m)
	msg_ex.send(robot, m[1], m)
end

local mapID2CopyID = {
[1001] = 400,
[1002] = 401,
[6001] = 6001,
[6002] = 6002,
[6003] = 6003,
}

local mapIDList = {
  1001,2001,2002,2003,2004,2005,9999
}

function change_scene(map_id)
		if mapID2CopyID[map_id] then
			local mm = get_cg("CG_COPY_ENTER")
			mm.copyID = mapID2CopyID[map_id]
			send(mm)
		else
			local mm = get_cg("CG_ASK_CHANGE_SCENE")
			mm.map_id = map_id
			mm.check  = 0
			send(mm)
		end
		
		print(robot_name, "change_scene ", map_id)
end
local ai = {}
function ai.change_scene()
  local mapid = math.random(1, #mapIDList)
  if mapid ~= cur_map_id then
      change_scene(mapid)
  end
end
function ai.heartbeat()
	send(get_cg("CG_HEART_BEAT"))
end

mw = mw or 0
mh = mh or 0
local interval =1 
function ai.move()
  if not obj_id or not mw then
      return
  end
	local mm = get_cg("CG_MOVE")
	mm.x = 0
	mm.y = 0
	mm.points = mm.points or {}
	mm.points[0] = 2
	mm.points[1] = (math.random(0, mw)*obj_id)%mw
	mm.points[2] = (math.random(0, mh)*obj_id)%mh
	send(mm)
	interval = 5	
	print(robot_name, "CG_MOVE")
	
end
function ai.chat()
  if obj_id == nil then
     return
  end
	local mm = get_cg("CG_CHAT")
	mm.msg_type = 1
	mm.msg = "world chat"
	--send(mm)
end
function ai.skill()
	if obj_id == nil then return end
	local mm = get_cg("CG_SKILL_FIRE")
	mm.x = 0
	mm.y = 0
	mm.skill_id = 309 -- 旋风斩
	mm.tx = 0
	mm.ty = 0
	mm.recv_id =0
	interval = 5
	send(mm)
end
function ai.nothing()end
local ai_percent = {
	heartbeat = 1,
	nothing = 20,
	move = 5,
	chat = 5,
	skill = 5,
--	change_scene = 1,
}

local lasttime = 0
ischange = ischange or nil
function handlerTime(robot)
	if not has_cg_ask_login then
		has_cg_ask_login = true
		local mm = get_cg("CG_ASK_LOGIN")
		mm.account = robot_name
    mm.fcm = 8197
    mm.ticket = "1111"
    mm.authkey = "2222"
    mm.timestamp = os.time()
    mm.serverid = 1
    mm.openid =""
    mm.openkey =""
    mm.pf=""
    mm.pfkey=""
    mm.yellowYearVip = 0
    mm.yellowVip = 0
    mm.yellowVipLv = 0
    mm.appContractId= "" 
    mm.zoneid = 0
    mm.isMiniClient = 0
    mm.x5sig = ""
    mm.blue= 0 
    mm.blueLv= 0 
    mm.blueYear= 0 
    mm.blueSuper= 0 

		send(mm)
		return
	end

  if os.time() - lasttime < interval then
      return
  end
  lasttime = os.time()
	local sum = 0
	for _, v in pairs(ai_percent) do
		sum = sum + v
	end

  
  if not ischange and cur_map_id and cur_map_id ~= map_id then
      change_scene(map_id)
      ischange = 1
      return
  end
	interval = 2
	local rand = math.random(1, sum)
	sum = 0
	for k, v in pairs(ai_percent) do
		sum = sum + v
		if rand <= sum then
			return ai[k]()
		end
	end
end

local handler = {}

function handler.GC_ZZ_HUMAN_INFO(msg)
--  print(robot_name, "GC_ZZ_HUMAN_INFO: name="..msg.name)
  obj_id = msg.id
end
function handler.GC_ENTER_SCENE(msg)
  local mm = get_cg("CG_ENTER_SCENE_OK")
  mm.map_id = msg.map_id
  mw = MapEx[msg.map_id].rect[-1][1][3]
  mh = MapEx[msg.map_id].rect[-1][1][4]
  
  send(mm)
  cur_map_id = msg.map_id
--  print(robot_name, "GC_ENTER_SCENE")  
end

function handler.GC_HUMAN_DIE(msg)
  if msg.obj_id == obj_id then  --复活
      local mm = get_cg("CG_REVIVE_NOW")
      send(mm)  
  end
end

local proto_name = {}
for k in pairs(handler) do
	proto_name[msg_ex.get_proto_id(k)] = k
end
function handlerMsg(proto_id)
	local name = proto_name[proto_id]
	if not name then
		return
	end
	local m = get_gc(name)
	msg_ex.recv(robot, proto_id, m)
	handler[name](m)
end
